#include "ws2812.h"
#include "main.h"
#include <math.h>

// 全局变量
static TIM_HandleTypeDef *ws2812_tim;
static WS2812_Color_t led_buffer[LED_NUM];

// WS2812时序参数 ± 150ns
#define T0H 350   // 0码高电平时间(ns) 
#define T1H 700   // 1码高电平时间(ns)
#define T0L 800   // 0码低电平时间(ns)
#define T1L 600   // 1码低电平时间(ns)
#define RESET 50000 // 复位时间(ns)

// 微秒延时函数
void Delay_ns(uint32_t nus)//n=1 330-360ns
{
	for(int i=0;i<nus;i++)
		__nop();
}

// 初始化函数
void WS2812_Init(TIM_HandleTypeDef *htim) {
    ws2812_tim = htim;
    WS2812_Clear();
}

// 设置单个LED颜色
void WS2812_SetColor(uint16_t index, WS2812_Color_t color) {
    if(index < LED_NUM) {
        led_buffer[index] = color;
    }
}

// 设置单个LED颜色(RGB格式)
void WS2812_SetColorRGB(uint16_t index, uint8_t red, uint8_t green, uint8_t blue) {
    if(index < LED_NUM) {
        led_buffer[index].red = red;
        led_buffer[index].green = green;
        led_buffer[index].blue = blue;
    }
}

// 发送一个字节数据
static void WS2812_SendByte(uint8_t byte) {
    for(uint8_t i = 0; i < 8; i++) {
        if(byte & (0x80 >> i)) {
            // 发送1码
            HAL_GPIO_WritePin(WS2812_GPIO_Port, WS2812_Pin, GPIO_PIN_SET);
            for (int i = 0; i < 8; i++) // 1400
              __NOP();
            HAL_GPIO_WritePin(WS2812_GPIO_Port, WS2812_Pin, GPIO_PIN_RESET);
            __NOP(); // 332
        } else {
            // 发送0码
            HAL_GPIO_WritePin(WS2812_GPIO_Port, WS2812_Pin, GPIO_PIN_SET);
            __NOP(); // 332
            HAL_GPIO_WritePin(WS2812_GPIO_Port, WS2812_Pin, GPIO_PIN_RESET);
            for (int i = 0; i < 8; i++) // 1400
              __NOP();
        }
    }
}

// 更新所有LED显示
void WS2812_Update(void) {
    
    for(uint16_t i = 0; i < LED_NUM; i++) {
        // WS2812需要按照GRB顺序发送数据
        WS2812_SendByte(led_buffer[i].green);
        WS2812_SendByte(led_buffer[i].red);
        WS2812_SendByte(led_buffer[i].blue);
    }
    
    // 发送复位信号
    HAL_GPIO_WritePin(WS2812_GPIO_Port, WS2812_Pin, GPIO_PIN_RESET);
    HAL_Delay(1);
}

// 清除所有LED
void WS2812_Clear(void) {
    for(uint16_t i = 0; i < LED_NUM; i++) {
        led_buffer[i].red = 0;
        led_buffer[i].green = 0;
        led_buffer[i].blue = 0;
    }
    WS2812_Update();
}
// 定义颜色结构体
typedef struct {
    float h;
    float s;
    float v;
} HSVColor;

// HSV转RGB函数
WS2812_Color_t HSVtoRGB(HSVColor hsv) {
    WS2812_Color_t rgb;
    float h = hsv.h;
    float s = hsv.s;
    float v = hsv.v;
    
    int i;
    float f, p, q, t;
    
    if (s == 0) {
        // 灰色
        rgb.red = rgb.green = rgb.blue = (uint8_t)(v * 255);
        return rgb;
    }
    
    h /= 60;            // 将色相转换为0-6的区间
    i = (int)floor(h);
    f = h - i;          // 小数部分
    p = v * (1 - s);
    q = v * (1 - s * f);
    t = v * (1 - s * (1 - f));
    
    switch (i) {
        case 0:
            rgb.red = (uint8_t)(v * 255);
            rgb.green = (uint8_t)(t * 255);
            rgb.blue = (uint8_t)(p * 255);
            break;
        case 1:
            rgb.red = (uint8_t)(q * 255);
            rgb.green = (uint8_t)(v * 255);
            rgb.blue = (uint8_t)(p * 255);
            break;
        case 2:
            rgb.red = (uint8_t)(p * 255);
            rgb.green = (uint8_t)(v * 255);
            rgb.blue = (uint8_t)(t * 255);
            break;
        case 3:
            rgb.red = (uint8_t)(p * 255);
            rgb.green = (uint8_t)(q * 255);
            rgb.blue = (uint8_t)(v * 255);
            break;
        case 4:
            rgb.red = (uint8_t)(t * 255);
            rgb.green = (uint8_t)(p * 255);
            rgb.blue = (uint8_t)(v * 255);
            break;
        default:        // case 5:
            rgb.red = (uint8_t)(v * 255);
            rgb.green = (uint8_t)(p * 255);
            rgb.blue = (uint8_t)(q * 255);
            break;
    }
    
    return rgb;
}

// 彩虹渐变效果
void WS2812_RainbowEffect(uint32_t delay_ms) {
    static float hue = 0.0f;
    HSVColor hsv;
    hsv.s = 1.0f;       // 饱和度
    hsv.v = 1.0f;       // 亮度
    
    while (1) {
        // 更新色相
        hue += 1.0f;
        if (hue >= 360.0f) {
            hue = 0.0f;
        }
        hsv.h = hue;
        
        // 将HSV转换为RGB并设置所有LED
        WS2812_Color_t color = HSVtoRGB(hsv);
        for (uint16_t i = 0; i < LED_NUM; i++) {
            WS2812_SetColor(i, color);
        }
        
        // 更新LED显示
        WS2812_Update();
        
        // 延时
        HAL_Delay(delay_ms);
    }
}

// 呼吸灯效果（单色）
void WS2812_BreathingEffect(uint8_t red, uint8_t green, uint8_t blue, uint32_t cycle_ms) {
    static float brightness = 0.0f;
    static int8_t direction = 1;
    const float step = 0.01f;
    
    while (1) {
        // 更新亮度
        brightness += direction * step;
        
        // 检查边界
        if (brightness >= 1.0f) {
            brightness = 1.0f;
            direction = -1;
        } else if (brightness <= 0.0f) {
            brightness = 0.0f;
            direction = 1;
        }
        
        // 设置所有LED
        for (uint16_t i = 0; i < LED_NUM; i++) {
            WS2812_SetColorRGB(i, 
                              (uint8_t)(red * brightness), 
                              (uint8_t)(green * brightness), 
                              (uint8_t)(blue * brightness));
        }
        
        // 更新LED显示
        WS2812_Update();
        
        // 延时
        HAL_Delay(cycle_ms * step);
    }
}

// 彩虹呼吸灯效果
void WS2812_RainbowBreathingEffect(uint32_t cycle_ms) {
    static float hue = 0.0f;
    static float brightness = 0.0f;
    static int8_t direction = 1;
    const float step = 0.01f;
    HSVColor hsv;
    hsv.s = 1.0f;       // 饱和度
    
    while (1) {
        // 更新色相
        hue += 0.5f;
        if (hue >= 360.0f) {
            hue = 0.0f;
        }
        hsv.h = hue;
        
        // 更新亮度
        brightness += direction * step;
        
        // 检查边界
        if (brightness >= 1.0f) {
            brightness = 1.0f;
            direction = -1;
        } else if (brightness <= 0.0f) {
            brightness = 0.0f;
            direction = 1;
        }
        
        hsv.v = brightness;
        
        // 将HSV转换为RGB并设置所有LED
        WS2812_Color_t color = HSVtoRGB(hsv);
        for (uint16_t i = 0; i < LED_NUM; i++) {
            WS2812_SetColor(i, color);
        }
        
        // 更新LED显示
        WS2812_Update();
        
        // 延时
        HAL_Delay(cycle_ms * step);
    }
}

// 跑马灯效果（单色）
void WS2812_RunningLightEffect(uint8_t red, uint8_t green, uint8_t blue, uint16_t length, uint32_t delay_ms) {
    static uint16_t position = 0;
    
    while (1) {
        // 清除所有LED
        WS2812_Clear();
        
        // 设置跑马灯位置
        for (uint16_t i = 0; i < length; i++) {
            uint16_t led_pos = (position + i) % LED_NUM;
            WS2812_SetColorRGB(led_pos, red, green, blue);
        }
        
        // 更新位置
        position = (position + 1) % LED_NUM;
        
        // 更新LED显示
        WS2812_Update();
        
        // 延时
        HAL_Delay(delay_ms);
    }
}

// 彩虹跑马灯效果
void WS2812_RainbowRunningLightEffect(uint16_t length, uint32_t delay_ms) {
    static uint16_t position = 0;
    static float hue = 0.0f;
    HSVColor hsv;
    hsv.s = 1.0f;       // 饱和度
    hsv.v = 1.0f;       // 亮度
    
    while (1) {
        // 更新色相
        hue += 5.0f;
        if (hue >= 360.0f) {
            hue = 0.0f;
        }
        
        // 清除所有LED
        WS2812_Clear();
        
        // 设置跑马灯位置
        for (uint16_t i = 0; i < length; i++) {
            uint16_t led_pos = (position + i) % LED_NUM;
            
            // 为每个LED设置不同的颜色
            hsv.h = fmod(hue + i * (360.0f / length), 360.0f);
            WS2812_Color_t color = HSVtoRGB(hsv);
            WS2812_SetColor(led_pos, color);
        }
        
        // 更新位置
        position = (position + 1) % LED_NUM;
        
        // 更新LED显示
        WS2812_Update();
        
        // 延时
        HAL_Delay(delay_ms);
    }
}